#include "BitArray.h"
#include "../embeddable/Embeddable.h"

#ifndef NULL
#define NULL 0
#endif

BitArray::BitArray()
{
	data = NULL;
	length = 0;
	allocated = 0;
	numberOfBits = 0;
}

BitArray::BitArray(unsigned long int bitNumber)
{
	unsigned long int rem = bitNumber % 8;
	unsigned long int result = bitNumber / 8;
	if(rem != 0)
		result++; //increment result if remainder is not zero.
	length = result;
	allocated = 1;
	data = (void*) Embeddable::malloc(sizeof(unsigned char)*length);
	numberOfBits = bitNumber;
}

BitArray::BitArray(void* pointer, unsigned long int l)
{
	allocated = 0;
	length = l;
	data = pointer;
	numberOfBits = length*8;
	
}

void BitArray::setBitNumber(unsigned long int bit)
{
	if(length * 8 > bit)
		numberOfBits = bit; //this works.
}

BitPointer BitArray::getBit(unsigned long int bit)
{
 	//find the byte the bit is located in
	unsigned long int byte = bit / 8; //equal to >> 3
	//assuming compiler optimizes
	//find real bit location in that byte
	unsigned char realBit = bit % 8; 
	volatile unsigned char* pointer = (volatile unsigned char*) (data + byte);
	BitPointer b = BitPointer(pointer, realBit);
	return b;
}

BitPointer BitArray::operator[](unsigned long int bit)
{
	return getBit(bit);
}

unsigned long int BitArray::size()
{
	return length;
}

BitArray::~BitArray()
{

	if(allocated == 1) //I need to deallocate the memory.
	{
		if(data != NULL)
		{

		Embeddable::free((void*) data);
		allocated = 0;
		data = NULL;

		}
	}
}

BitArray::BitArray(const BitArray& array)
{
	//need to make a new copy of the memory
	allocated = array.allocated;
	if(allocated == 0)
	{
		data = array.data;
		length = array.length;
	}
	else
	{
		data = Embeddable::malloc(array.length);
		unsigned char* temp = (unsigned char* ) data;
		unsigned char* temp2 = (unsigned char*) array.data;
		//copy the data over.	
		unsigned int i = 0;
		for(i = 0; i < array.length; i++)
		{
			temp[i] = temp2[i];
		}
		length = array.length;
	}
}

BitArray& BitArray::operator=(const BitArray& array)
{
	//if(*this == array)
	//	return *this;
	
	if(allocated == 1) 
	{
		//free memory now
		Embeddable::free((void*) data);
	}
	//need to make a new copy of the memory
	allocated = array.allocated;
	if(allocated == 0)
	{
		data = array.data;
		length = array.length;
	}
	else
	{
		data = Embeddable::malloc(array.length);
		unsigned char* temp = (unsigned char* ) data;
		unsigned char* temp2 = (unsigned char*) array.data;
		//copy the data over.	
		unsigned int i = 0;
		for(i = 0; i < array.length; i++)
		{
			temp[i] = temp2[i];
		}
		length = array.length;
	}
	return *this;
}



void BitArray::setByte(unsigned char value, unsigned char index)
{
	if(index < length)
	{
		unsigned char* v = (unsigned char*) data;
		v[index] = value;
	}
}

unsigned char BitArray::getByte(unsigned char index)
{
	if(index < length)
	{
		unsigned char* v = (unsigned char*) data;
		return v[index];
	}
	else
		return -1;
}


